#include "Cats/CatStates/CatState.h"
#include "Cats/CatStates/CatState_Base_Injured.h"
#include "Cats/BaseCat.h"
#include "Cats/CatSpriteLoader.h"

#include "Supporting/SoundLoader.h"
#include "Supporting/Enums/EnumSoundType.h"
#include "Supporting/Enums/EnumCatAnimation.h"

CatState_Base_Injured::CatState_Base_Injured(BaseCat* pCatRef):CatState(pCatRef)
{
	_isInvulnerable = false;
	_invulTimer = 0;
	_injuredAnimationDuration = 0;
}

CatState_Base_Injured::~CatState_Base_Injured()
{

}

void CatState_Base_Injured::runOnEnter()
{
	//play an injured animation and calculate its duration
	EnumCatAnimation chosenAnimation = playInjuredAnimation();
	_injuredAnimationDuration = CatSpriteLoader::getAnimationDuration(_pCatRef->getCatType(), chosenAnimation);

	//play any status effects animation
	playStatusEffectAnimation();

	//if its not a status effect
	if(_pCatRef->getInjuryType() != INJURY_WET)
	{
		//if the cat is still alive
		if (!_pCatRef->isDead())
		{
			//play audio for injured animation
			playInjuredAudio(chosenAnimation);

			//injured state is invulnerable
			_isInvulnerable = true;
			_invulTimer = _pCatRef->getBaseInvulDuration();

			//play blinking animation
			playInvulnerableAnimation();
		}
	}
	else
		_isInvulnerable = false;
}

void CatState_Base_Injured::update(float timeDiff)
{
	bool exitState = false;

	//if injured state is invulnerable, wait till invulnerability ends before exiting state
	if (_isInvulnerable)
	{
		_invulTimer -= timeDiff;
		if (_invulTimer <= 0)
			exitState = true;
	}
	//based on the injured animation duration
	else
	{
		_injuredAnimationDuration -= timeDiff;
		if(_injuredAnimationDuration <= 0)
			exitState = true;
	}

	//time to exit current state
	if (exitState)
	{
		//if cat is dead, go to dying state
		if (_pCatRef->getHealth() <= 0)
		{
			//do not clean up INJURY TYPE of cats here. its is required for CAT_DYING state
			//stop all animations
			_pCatRef->stopImmuneEffectLayer();
			_pCatRef->stopStatusEffectsLayer();
			_pCatRef->stopAllActions();
			_pCatRef->setNextCatState(CAT_DYING);
		}
		//return to previous cat state
		else
		{
			//stop blinking animation
			_pCatRef->setNextCatState(_pCatRef->getPreviousCatState());
			//reset the injured type
			_pCatRef->setInjuryType(INJURY_NORMAL);
		}
	}
}

void CatState_Base_Injured::onExit()
{
	CatState::onExit();

	SoundLoader::endSound(CAT_INJURED_SOUND);

	//reset variables
	_injuredAnimationDuration = 0;
	_invulTimer = 0;
	_isInvulnerable = false;
}

EnumCatAnimation CatState_Base_Injured::playInjuredAnimation()
{
	EnumCatAnimation catAnim;
	switch(_pCatRef->getInjuryType())
	{
	case INJURY_NORMAL:
		catAnim = CAT_ANIM_INJURED;
		break;
	case INJURY_ZAPPED:
		catAnim = CAT_ANIM_ZAPPED;
		break;
	case INJURY_BURNT:
		catAnim = CAT_ANIM_BURNT;
		break;
	case INJURY_EARTHQUAKE:
		catAnim = CAT_ANIM_EARTHQUAKE;
		break;
	default:
		catAnim = CAT_ANIM_INJURED;
	}

	//play injured animation
	_pCatRef->stopAllActions();
	_pCatRef->runAction(CatSpriteLoader::getCatAnimation(_pCatRef->getCatType(), catAnim));

	return catAnim;
}

void CatState_Base_Injured::playInjuredAudio(EnumCatAnimation catAnim)
{
	switch(catAnim)
	{
	case CAT_ANIM_INJURED: //normal injury sound
		SoundLoader::playSound(CAT_INJURED_SOUND);
		break;

	case CAT_ANIM_ZAPPED:		
		break;

	case CAT_ANIM_BURNT:
		break;

	default:
		break;
	}
}

void CatState_Base_Injured::playStatusEffectAnimation()
{
	switch (_pCatRef->getInjuryType())
	{
	case INJURY_WET:
		_pCatRef->stopStatusEffectsLayer();
		_pCatRef->getStatusEffectsLayer()->runAction(CatSpriteLoader::getCatStatusAnimation(CAT_ANIM_WET));
	}
}

void CatState_Base_Injured::playInvulnerableAnimation()
{
	CCActionInterval* blink = CCBlink::create(_pCatRef->getBaseInvulDuration(), INJURED_BLINKING_TIMES);
	_pCatRef->runAction(blink);
}

void CatState_Base_Injured::playSkillImmuneAnimation()
{
	_pCatRef->stopImmuneEffectLayer();
	_pCatRef->getImmuneEffectLayer()->runAction(CatSpriteLoader::getCatStatusAnimation(CAT_ANIM_IMMUNE));
}

void CatState_Base_Injured::onPause()
{
	SoundLoader::endSound(CAT_INJURED_SOUND);
}
